import {
  i18n,
  nmAppErrorLog,
  nmAppLog,
  setObject,
} from '@app-nextmesh/common/utils';
import { LoadingButton, showLoading } from '@app-nextmesh/components';
import {
  FormField,
  FormNativeSelect,
} from '@app-nextmesh/components/Forms/components';
import { documentV2 } from '@app-nextmesh/domain';
import { useProjectStore } from '@app-nextmesh/store/project';
import { useTasksStore } from '@app-nextmesh/store/tasks';
import { ITask } from '@app-nextmesh/types';
import { Modal } from 'antd';
import { cloneDeep, isArray } from 'lodash';
import { useEffect, useRef, useState } from 'react';
import BaseForm from '../BaseForm';
import { IProps } from './types';

export default function TaskForm({
  data: initData,
  onClose,
  onUpdate,
  onUpdateTitle,
}: IProps) {
  const [data, setData] = useState<ITask>(null);
  const resetTitle = useRef({ reset: true, oldTitle: '' });
  const projectInfo = useProjectStore((state) => state.projectInfo);
  const simulations = useProjectStore(
    (state) => state.projectInfo?.simulations,
  );
  const { tasks, setTasks } = useTasksStore();
  const [isModalOpen, setIsModalOpen] = useState(false);

  useEffect(() => {
    const newData = cloneDeep(initData.formData);
    setData(newData);
    resetTitle.current = { reset: true, oldTitle: newData.name };
    return () => {
      if (resetTitle.current.reset) {
        // 重置标题
        onUpdateTitle?.(resetTitle.current.oldTitle);
      }
    };
  }, [initData.formData]);
  /**
   * 检查任务状态
   */
  useEffect(() => {
    const uuid = initData.formData?.uuid;
    nmAppLog('TaskForm check tasks', {
      uuid,
      tasks,
    });
    if (!isArray(tasks) || !uuid) {
      return;
    }
    const task = tasks.find((task) => task?.uuid === uuid);
    if (!task) {
      return;
    }
    setData(task);
  }, [tasks, initData?.formData?.uuid]);
  function handleUpdateTitle(title: string) {
    const newData = { ...data };
    newData.name = title;
    setData(newData);
    onUpdateTitle?.(title);
  }
  const handleInputChange = (name: string, value: string) => {
    const newData = { ...data };
    setObject(newData, name, value);
    setData(newData);
  };
  const handleOk = async () => {
    const hide = showLoading();
    try {
      await documentV2.updateTask(data);
      onUpdate(data);
      resetTitle.current.reset = false;
      onClose();
    } catch (error) {
      nmAppErrorLog(error);
    } finally {
      hide();
    }
  };
  function handleClose() {
    onClose();
  }
  const handleGenerate = async (task: ITask) => {
    setIsModalOpen(false);
    const hide = showLoading();
    try {
      if (task.status === 'STARTED') {
        await documentV2.cancelTask(task.uuid);
        task.status = 'CANCELING';
      } else {
        // await documentV2.updateTask({ name: data.name });
        await documentV2.executeTask(task.uuid);
        task.status = 'STARTED';
        task.progress = 0;
      }
      onUpdate(task);

      // 更新tasks，会触发useEffect 更新task状态
      const oldTask = tasks.find(({ uuid }) => uuid === task.uuid);
      if (oldTask) {
        oldTask.status = task.status;
        oldTask.progress = task.progress;
        setTasks([...tasks]);
      }
    } catch (error) {
      nmAppErrorLog(error);
    } finally {
      hide();
    }
  };
  if (!data) {
    return <></>;
  }
  let loadingButtonTitle = '';
  let loading = false;
  switch (data.status) {
    case 'STARTED':
      loadingButtonTitle = i18n.t('cancelSolve');
      break;
    case 'CREATED':
      loadingButtonTitle = i18n.t('solve');
      break;
    case 'CANCELING':
      loadingButtonTitle = i18n.t('canceling');
      loading = true;
      break;
    default:
      loadingButtonTitle = i18n.t('resolve');
      break;
  }
  const options =
    simulations?.map((s) => ({ label: s.name, value: s.uuid })) || [];
  return (
    <>
      <BaseForm
        disabled={projectInfo.readonly}
        title={data.name}
        titleEditable={false}
        onClose={handleClose}
        onOk={handleOk}
        hideConfirm
        progressInfo={{
          progress: data.progress,
          status: data.status,
        }}
        updateTitle={handleUpdateTitle}
        footerRight={
          <LoadingButton
            title={loadingButtonTitle}
            loading={loading}
            danger={data.status === 'STARTED'}
            onClick={() => {
              if (data.status === 'STARTED') {
                setIsModalOpen(true);
              } else {
                handleGenerate(data);
              }
            }}
          />
        }>
        <FormField label={i18n.t('selectSimulation')}>
          <FormNativeSelect
            value={data.moduleId}
            options={options}
            disabled
            onChange={(value) => handleInputChange('moduleId', value as string)}
          />
        </FormField>
      </BaseForm>
      <Modal
        title={i18n.t('tip')}
        open={isModalOpen}
        onOk={() => handleGenerate(data)}
        okText={i18n.t('sure')}
        onCancel={() => setIsModalOpen(false)}
        cancelText={i18n.t('cancel')}>
        <p>{i18n.t('sureToCancel')}</p>
      </Modal>
    </>
  );
}
